#ifndef __SCENE_HPP__
#define __SCENE_HPP__ 1

#include <vector>
#include <functional>

#include <FreeImagePlus.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

class CTerrain;
class EventHandler;
struct Event;
class CCamera;
struct ShaderProgram;
class CShader;
struct RenderData;
class CRenderer;
struct VertexBuffer;
struct VertexArray;
struct Texture;

struct SceneData
{
	SceneData(EventHandler& eventHandler, CRenderer& renderer, RenderData* renderData);
	~SceneData();

	const SceneData& operator=(const SceneData& other);

	std::vector<ShaderProgram*> programs;
	std::vector<VertexArray*> VAOs;
	std::vector<VertexBuffer*> VBOs;
	std::vector<Texture*> textures;

	std::vector<CCamera*> cameras;

	std::vector<CTerrain*> terrains;

	glm::mat4 projection;
	glm::mat4 view;
	glm::mat4 model;

	EventHandler& eventHandler;
	CRenderer& renderer;
	RenderData* renderData;

	CShader* shaderUtil;
};

class CScene
{
public:
	CScene() { }

	virtual bool Initialize() = 0;
	virtual bool Destroy() = 0;
	virtual bool Update() = 0;
	virtual bool Draw() = 0;

private:
	CScene(const CScene&) { }
	const CScene& operator=(const CScene&) { }
};

class MyScene : public CScene
{
public:
	MyScene(SceneData* sceneData);
	~MyScene();

	bool Initialize();
	bool Update();
	bool Draw();
	bool Destroy();

	CCamera* GetCameraByName(const std::string& name);

	// Event handlers
	bool OnWindowResize(Event* evt);

private:
	MyScene(const MyScene&);
	const MyScene& operator=(const MyScene&);

	SceneData* sceneData;
};

#endif // __SCENE_HPP__
